package com.epoch.base.export;

import java.io.BufferedWriter;
import java.io.IOException;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

public class SqlExporter extends AbstractTextExporter {
    private static final String SQL_SPACE = " ";
    private static final String SQL_TABLE_QUOT = "`";
    private static final String SQL_STR_QUOT = "'";
    private static final String SQL_PARENTHESE_OPEN = "(";
    private static final String SQL_PARENTHESE_CLOSE = ")";
    private static final String SQL_COMMA = ",";
    private static final String SQL_SEMICOLON = ";";
    private static final String SQL_ESC = "\\";
    private static final String SQL_INSERT_INTO = "INSERT INTO";
    private static final String SQL_VALUES = "VALUES";

    @Override
    protected void doTextExport(BufferedWriter writer, Collection<?> data, List<HeadMeta> headMetas,
        Map<Integer, IExportConvertor> indexCvtorMap, Map<String, IExportConvertor> fieldCvtorMap,
        Map<String, Object> params) throws IOException, ExportException {
        if (CollectionUtils.isNotEmpty(headMetas)) {
            Object tableNameObj = params == null ? null : params.get(ExportConstant.EXPORT_TABLE_NAME);
            String tableName = tableNameObj == null ? null : tableNameObj.toString();
            writer.write(SQL_INSERT_INTO);
            writer.write(SQL_SPACE);
            writer.write(SQL_TABLE_QUOT);
            writer.write(StringUtils.trimToEmpty(tableName));
            writer.write(SQL_TABLE_QUOT);
            writer.write(SQL_SPACE);
            writer.write(SQL_PARENTHESE_OPEN);
            int c = 0;
            int cols = headMetas.size();
            for (; c < cols; c++) {
                if (c > 0) {
                    writer.write(SQL_COMMA);
                }
                HeadMeta meta = headMetas.get(c);
                String title = meta.getTitle();
                writer.write(this.buildSqlStr(title));
            }
            writer.write(SQL_PARENTHESE_CLOSE);
            writer.write(SQL_SPACE);
            writer.write(SQL_VALUES);
            writer.write(SQL_SPACE);
            if (data != null) {
                int r = 0;
                for (Object rowData : data) {
                    if (r > 0) {
                        writer.write(SQL_COMMA);
                    }
                    writer.write(SQL_PARENTHESE_OPEN);
                    if (rowData != null) {
                        for (c = 0; c < cols; c++) {
                            if (c > 0) {
                                writer.write(SQL_COMMA);
                            }
                            HeadMeta meta = headMetas.get(c);
                            String field = meta.getField();
                            Object val = this.obtainFieldVal(rowData, indexCvtorMap, fieldCvtorMap, field, r, c);
                            String valStr = null;
                            if (val instanceof Date) {
                                valStr = ExportConstant.DATETIME_FORMAT.format((Date)val);
                            } else if (val != null) {
                                valStr = val.toString();
                            }
                            writer.write(this.buildSqlStr(valStr));
                        }
                    }
                    writer.write(SQL_PARENTHESE_CLOSE);
                    r++;
                }
            }
            writer.write(SQL_SEMICOLON);
        }
    }

    @Override
    public String getFileNameExt() {
        return ".sql";
    }

    private String buildSqlStr(String str) {
        String result = StringUtils.trimToEmpty(str);
        result = result.replace(SQL_ESC, SQL_ESC + SQL_ESC);
        result = result.replace(SQL_STR_QUOT, SQL_ESC + SQL_STR_QUOT);
        result = SQL_STR_QUOT + result + SQL_STR_QUOT;
        return result;
    }
}
